package com.varian.tool.extend;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * @author ben
 * @since 2024/6/24
 */
@RequiredArgsConstructor
public class Selector<P, R> {
    @Getter
    private boolean selected = false;
    private Function<P, R> factory;
    private final P param;

    public static <P, R> Selector<P, R> of(P param) {
        return new Selector<>(param);
    }

    public Selector<P, R> test(Predicate<P> tester, R value) {
        return test(Branch.of(tester, p -> value));
    }

    public Selector<P, R> test(Predicate<P> tester, Function<P, R> factory) {
        return test(Branch.of(tester, factory));
    }

    public Selector<P, R> test(Branch<P, R> branch) {
        if (!selected) {
            boolean pass = branch.tester().test(param);
            if (pass) {
                selected = true;
                factory = branch.factory();
            }
        }
        return this;
    }

    public R or(Supplier<R> supplier) {
        return selected ? this.factory.apply(param) : supplier.get();
    }


    public R or(R r) {
        return or(() -> r);
    }

    public R orNull() {
        return or(() -> null);
    }
}
